package cn.lg.soar.common.util.current;

import cn.lg.soar.common.exceptions.AuthenticationException;

import java.util.function.Supplier;

/**
 * 当前用户上下文
 * @author luguoxiang
 * @date 2022/3/29
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
public class UserContext {

    protected static final ICurrentUser EMPTY_CURRENT_USER = new CurrentUser();
    static ThreadLocal<ICurrentUser> CURRENT_USER_THREAD_LOCAL = new ThreadLocal<ICurrentUser>(){
        @Override
        protected ICurrentUser initialValue() {
            return loader.get();
        }
    };
    /**
     * 使用加载器实现懒加载
     */
    private static Supplier<ICurrentUser> loader = () -> null;

    /**
     * 判断是否登录的
     * @return
     */
    public static boolean isLogin() {
        return CURRENT_USER_THREAD_LOCAL.get() != null;
    }

    /**
     * 获取当前用户（未登录的抛异常）
     * @return
     */
    public static ICurrentUser getUser() {
        ICurrentUser currentUser = CURRENT_USER_THREAD_LOCAL.get();
        if (currentUser == null) {
            throw new AuthenticationException();
        }
        return currentUser;
    }

    /**
     * 获取当前用户id（未登录的抛异常）
     * @return
     */
    public static Long getUserId() {
        return getUser().getId();
    }

    /**
     * 取当前用户（未登录的返回null）
     * @return
     */
    public static ICurrentUser getUserNullable() {
        return CURRENT_USER_THREAD_LOCAL.get();
    }

    /**
     * 获取当前用户id（未登录的返回null）
     * @return
     */
    public static Long getUserIdNullable() {
        ICurrentUser currentUser = CURRENT_USER_THREAD_LOCAL.get();
        if (currentUser == null) {
            return null;
        }
        return currentUser.getId();
    }

    /**
     * 取当前用户（未登录的返回默认值）
     * @return
     */
    public static ICurrentUser getUserOrDef() {
        ICurrentUser currentUser = CURRENT_USER_THREAD_LOCAL.get();
        return currentUser == null ? EMPTY_CURRENT_USER : currentUser;
    }

    /**
     * 设置
     * @param currentUser
     */
    static void set(ICurrentUser currentUser) {
        CURRENT_USER_THREAD_LOCAL.set(currentUser);
    }

    /**
     * 删除
     */
    static void remove() {
        CURRENT_USER_THREAD_LOCAL.remove();
    }

    /**
     * 设置加载器
     * @param loader
     */
    static void setLoader(Supplier<ICurrentUser> loader){
        UserContext.loader = loader;
    }

}
